1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-03 14:25:37 +02:00

Initial commit of UI and Freemarker plugins.

This commit is contained in:
Doug Schaefer 2016-02-20 11:40:31 -05:00
parent 4a479d68fb
commit e419c4bd0a
29 changed files with 1346 additions and 0 deletions

1
bundles/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
*/bin/

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1 @@
/bin/

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.tools.templates.freemarker</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8

View file

@ -0,0 +1,12 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Eclipse Tools
Bundle-SymbolicName: org.eclipse.tools.templates.freemarker
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: org.eclipse.tools.templates.freemarker.internal.Activator
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.core.resources,
org.freemarker
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.tools.templates.freemarker

View file

@ -0,0 +1,24 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>About</title></head>
<body lang="EN-US">
<h2>About This Content</h2>
<p>June 22, 2007</p>
<h3>License</h3>
<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
indicated below, the Content is provided to you under the terms and conditions of the
Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
For purposes of the EPL, "Program" will mean the Content.</p>
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
being redistributed by another party ("Redistributor") and different terms and conditions may
apply to your use of any object code in the Content. Check the Redistributor's license that was
provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
indicated below, the terms and conditions of the EPL still apply to any source code in the Content
and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
</body></html>

View file

@ -0,0 +1,5 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
about.html

View file

@ -0,0 +1,210 @@
package org.eclipse.tools.templates.freemarker;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.tools.templates.freemarker.internal.Activator;
import org.osgi.framework.Bundle;
import freemarker.cache.TemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public abstract class FMGenerator implements TemplateLoader {
private final Configuration templateConfig;
private Bundle bundle;
private String manifestPath;
private TemplateManifest manifest;
private List<IFile> filesToOpen = new ArrayList<>();
protected FMGenerator() {
templateConfig = new Configuration(Configuration.VERSION_2_3_22);
templateConfig.setTemplateLoader(this);
}
public void setBundle(Bundle bundle) {
this.bundle = bundle;
}
public void setTemplateManifestPath(String manifestPath) {
this.manifestPath = manifestPath;
}
public TemplateManifest getManifest() {
return manifest;
}
protected Class<? extends TemplateManifest> getManifestClass() {
return TemplateManifest.class;
}
public void generate(Map<String, Object> model, IProgressMonitor monitor) throws CoreException {
manifest = null;
try {
// load manifest file
StringWriter writer = new StringWriter();
loadFile(manifestPath, model, writer); // $NON-NLS-1$
JAXBContext xmlContext = JAXBContext.newInstance(getManifestClass());
Unmarshaller unmarshaller = xmlContext.createUnmarshaller();
manifest = (TemplateManifest) unmarshaller.unmarshal(new StringReader(writer.toString()));
} catch (JAXBException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Loading template manifest", e));
}
// generate files
if (manifest != null) {
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IFile fileToShow = null;
for (FileTemplate fileTemplate : manifest.getFiles()) {
IPath destPath = new Path(fileTemplate.getDest());
IProject project = root.getProject(destPath.segment(0));
IFile file = project.getFile(destPath.removeFirstSegments(1));
if (!fileTemplate.isCopy()) {
generateFile(fileTemplate.getSrc(), model, file, monitor);
} else {
try {
URL url = FileLocator.find(bundle, new Path(fileTemplate.getSrc()), null);
try (InputStream in = url.openStream()) {
createParent(file, monitor);
if (file.exists()) {
file.setContents(in, true, true, monitor);
} else {
file.create(in, true, monitor);
}
}
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(),
"Reading file " + fileTemplate.getSrc(), e));
}
}
if (fileTemplate.isOpen()) {
if (fileTemplate.isShow()) {
if (fileToShow != null) {
filesToOpen.add(fileToShow);
}
fileToShow = file;
} else {
filesToOpen.add(file);
}
}
}
if (fileToShow != null) {
filesToOpen.add(fileToShow);
}
}
}
public void loadFile(String templateFile, Object model, Writer out) throws CoreException {
try {
Template template = templateConfig.getTemplate(templateFile);
template.process(model, out);
} catch (IOException | TemplateException e) {
throw new CoreException(
new Status(IStatus.ERROR, Activator.getId(), "Processing template " + templateFile, e));
}
}
public void generateFile(String templateFile, final Object model, final IFile outputFile, IProgressMonitor monitor)
throws CoreException {
try (StringWriter writer = new StringWriter()) {
loadFile(templateFile, model, writer);
try (ByteArrayInputStream in = new ByteArrayInputStream(
writer.getBuffer().toString().getBytes(StandardCharsets.UTF_8))) {
createParent(outputFile, monitor);
if (outputFile.exists()) {
outputFile.setContents(in, true, true, monitor);
} else {
outputFile.create(in, true, monitor);
}
}
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Generating file " + templateFile, e));
}
}
public static void createParent(IResource child, IProgressMonitor monitor) throws CoreException {
if (child == null)
return;
IContainer container = child.getParent();
if (container.exists()) {
return;
}
IFolder parent = container.getAdapter(IFolder.class);
createParent(parent, monitor);
parent.create(true, true, monitor);
}
public IFile[] getFilesToOpen() {
// TODO Auto-generated method stub
return null;
}
@Override
public Object findTemplateSource(String name) throws IOException {
return FileLocator.find(bundle, new Path(name), null);
}
@Override
public long getLastModified(Object source) {
try {
URL url = (URL) source;
if (url.getProtocol().equals("file")) { //$NON-NLS-1$
File file = new File(url.toURI());
return file.lastModified();
} else {
return 0;
}
} catch (URISyntaxException e) {
return 0;
}
}
@Override
public Reader getReader(Object source, String encoding) throws IOException {
URL url = (URL) source;
return new InputStreamReader(url.openStream(), encoding);
}
@Override
public void closeTemplateSource(Object arg0) throws IOException {
// Nothing
}
}

View file

@ -0,0 +1,70 @@
package org.eclipse.tools.templates.freemarker;
import java.net.URI;
import java.util.Map;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
public abstract class FMProjectGenerator extends FMGenerator {
private String projectName;
private URI locationURI;
private IProject[] referencedProjects;
private IProject project;
protected abstract String[] getProjectNatures();
public void setProjectName(String projectName) {
this.projectName = projectName;
}
public void setLocationURI(URI locationURI) {
this.locationURI = locationURI;
}
public void setReferencedProjects(IProject[] referencedProjects) {
this.referencedProjects = referencedProjects;
}
public IProject getProject() {
return project;
}
@Override
public void generate(Map<String, Object> model, IProgressMonitor monitor) throws CoreException {
// Make sure project name is in model
model.put("projectName", projectName); //$NON-NLS-1$
// Create the project
createProject(monitor);
// Generate the files
super.generate(model, monitor);
}
protected void createProject(IProgressMonitor monitor) throws CoreException {
IWorkspace workspace = ResourcesPlugin.getWorkspace();
project = workspace.getRoot().getProject(projectName);
if (!project.exists()) {
IProjectDescription description = workspace.newProjectDescription(projectName);
description.setLocationURI(locationURI);
if (referencedProjects != null) {
description.setReferencedProjects(referencedProjects);
}
description.setNatureIds(getProjectNatures());
project.create(description, monitor);
project.open(monitor);
} else {
// TODO make sure it's got all our settings or is this an error
// condition?
}
}
}

View file

@ -0,0 +1,57 @@
package org.eclipse.tools.templates.freemarker;
import javax.xml.bind.annotation.XmlAttribute;
public class FileTemplate {
private String src;
private String dest;
private boolean open;
private boolean show;
private boolean copy;
@XmlAttribute(name = "src")
public String getSrc() {
return src;
}
public void setSrc(String src) {
this.src = src;
}
@XmlAttribute(name = "dest")
public String getDest() {
return dest;
}
public void setDest(String dest) {
this.dest = dest;
}
@XmlAttribute(name = "open")
public boolean isOpen() {
return open;
}
public void setOpen(boolean open) {
this.open = open;
}
@XmlAttribute(name = "show")
public boolean isShow() {
return show;
}
public void setShow(boolean show) {
this.show = show;
}
@XmlAttribute(name = "copy")
public boolean isCopy() {
return copy;
}
public void setCopy(boolean copy) {
this.copy = copy;
}
}

View file

@ -0,0 +1,18 @@
package org.eclipse.tools.templates.freemarker;
import javax.xml.bind.annotation.XmlAttribute;
public class SourceRoot {
private String dir;
@XmlAttribute(name = "dir")
public String getDir() {
return dir;
}
public void setDir(String dir) {
this.dir = dir;
}
}

View file

@ -0,0 +1,39 @@
/*******************************************************************************
* Copyright (c) 2016 QNX Software Systems 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
*******************************************************************************/
package org.eclipse.tools.templates.freemarker;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class TemplateManifest {
private List<FileTemplate> files;
private List<SourceRoot> srcRoots;
@XmlElement(name = "file")
public List<FileTemplate> getFiles() {
return files;
}
public void setFiles(List<FileTemplate> files) {
this.files = files;
}
@XmlElement(name = "srcRoot")
public List<SourceRoot> getSrcRoots() {
return srcRoots;
}
public void setSrcRoots(List<SourceRoot> srcRoots) {
this.srcRoots = srcRoots;
}
}

View file

@ -0,0 +1,33 @@
/*******************************************************************************
* Copyright (c) 2016 QNX Software Systems 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
*******************************************************************************/
package org.eclipse.tools.templates.freemarker.internal;
import org.eclipse.core.runtime.Plugin;
import org.osgi.framework.BundleContext;
public class Activator extends Plugin {
private static Activator plugin;
@Override
public void start(BundleContext bundleContext) throws Exception {
super.start(bundleContext);
plugin = this;
}
@Override
public void stop(BundleContext bundleContext) throws Exception {
super.stop(bundleContext);
plugin = null;
}
public static String getId() {
return plugin.getBundle().getSymbolicName();
}
}

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.tools.templates.ui</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8

View file

@ -0,0 +1,13 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Ui
Bundle-SymbolicName: org.eclipse.tools.templates.ui;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: org.eclipse.tools.templates.ui.internal.Activator
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.ui.ide,
org.eclipse.core.resources
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.tools.templates.ui

View file

@ -0,0 +1,24 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>About</title></head>
<body lang="EN-US">
<h2>About This Content</h2>
<p>June 22, 2007</p>
<h3>License</h3>
<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
indicated below, the Content is provided to you under the terms and conditions of the
Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
For purposes of the EPL, "Program" will mean the Content.</p>
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
being redistributed by another party ("Redistributor") and different terms and conditions may
apply to your use of any object code in the Content. Check the Redistributor's license that was
provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
indicated below, the terms and conditions of the EPL still apply to any source code in the Content
and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
</body></html>

View file

@ -0,0 +1,6 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
about.html,\
plugin.xml

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension-point id="templates" name="New Element Templates" schema="schema/templates.exsd"/>
</plugin>

View file

@ -0,0 +1,187 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Schema file written by PDE -->
<schema targetNamespace="org.eclipse.tools.templates.ui" xmlns="http://www.w3.org/2001/XMLSchema">
<annotation>
<appinfo>
<meta.schema plugin="org.eclipse.tools.templates.ui" id="templates" name="Templates"/>
</appinfo>
<documentation>
[Enter description of this extension point.]
</documentation>
</annotation>
<element name="extension">
<annotation>
<appinfo>
<meta.element />
</appinfo>
</annotation>
<complexType>
<sequence>
<element ref="tag" minOccurs="0" maxOccurs="unbounded"/>
<element ref="template" minOccurs="0" maxOccurs="unbounded"/>
<element ref="templateExtension" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<attribute name="point" type="string" use="required">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="id" type="string">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="name" type="string">
<annotation>
<documentation>
</documentation>
<appinfo>
<meta.attribute translatable="true"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>
<element name="template">
<complexType>
<sequence>
<element ref="tagReference" minOccurs="1" maxOccurs="unbounded"/>
<element ref="description"/>
</sequence>
<attribute name="id" type="string" use="required">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="label" type="string" use="required">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="icon" type="string">
<annotation>
<documentation>
</documentation>
<appinfo>
<meta.attribute kind="resource"/>
</appinfo>
</annotation>
</attribute>
<attribute name="wizard" type="string" use="required">
<annotation>
<documentation>
</documentation>
<appinfo>
<meta.attribute kind="java" basedOn=":org.eclipse.ui.INewWizard"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>
<element name="description" type="string">
</element>
<element name="tag">
<complexType>
<attribute name="id" type="string" use="required">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="label" type="string" use="required">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
</complexType>
</element>
<element name="tagReference">
<complexType>
<attribute name="id" type="string" use="required">
<annotation>
<documentation>
</documentation>
<appinfo>
<meta.attribute kind="identifier" basedOn="org.eclipse.tools.templates.ui.templates/tag/@id"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>
<element name="templateExtension">
<complexType>
<sequence>
<element ref="tagReference" minOccurs="1" maxOccurs="unbounded"/>
</sequence>
<attribute name="templateId" type="string" use="required">
<annotation>
<documentation>
</documentation>
<appinfo>
<meta.attribute kind="identifier" basedOn="org.eclipse.tools.templates.ui.templates/template/@id"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>
<annotation>
<appinfo>
<meta.section type="since"/>
</appinfo>
<documentation>
[Enter the first release in which this extension point appears.]
</documentation>
</annotation>
<annotation>
<appinfo>
<meta.section type="examples"/>
</appinfo>
<documentation>
[Enter extension point usage example here.]
</documentation>
</annotation>
<annotation>
<appinfo>
<meta.section type="apiinfo"/>
</appinfo>
<documentation>
[Enter API information here.]
</documentation>
</annotation>
<annotation>
<appinfo>
<meta.section type="implementation"/>
</appinfo>
<documentation>
[Enter information about supplied implementation of this extension point.]
</documentation>
</annotation>
</schema>

View file

@ -0,0 +1,103 @@
package org.eclipse.tools.templates.ui;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.tools.templates.ui.internal.Activator;
import org.eclipse.tools.templates.ui.internal.Tag;
import org.eclipse.tools.templates.ui.internal.TagListViewer;
import org.eclipse.tools.templates.ui.internal.Template;
import org.eclipse.tools.templates.ui.internal.TemplateExtension;
import org.eclipse.tools.templates.ui.internal.TemplateTable;
import org.eclipse.ui.IWorkbenchWizard;
public class TemplateSelectionPage extends WizardPage {
private final String[] requestedTags;
private ListViewer tagList;
private TemplateTable templateTable;
public TemplateSelectionPage(String pageName, String... tags) {
super(pageName);
this.requestedTags = tags;
}
@Override
public void createControl(Composite parent) {
SashForm form = new SashForm(parent, SWT.HORIZONTAL);
setControl(form);
tagList = new TagListViewer(form, SWT.BORDER);
tagList.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
}
});
templateTable = new TemplateTable(form, SWT.V_SCROLL | SWT.SINGLE | SWT.BORDER);
templateTable.getTable().addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
setPageComplete(templateTable.getSelectedTemplate() != null);
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
widgetSelected(e);
getContainer().showPage(getNextPage());
}
});
TemplateExtension templateExtension = Activator.getTemplateExtension();
List<Template> templates = new ArrayList<>();
for (Template template : templateExtension.getTemplates()) {
for (String requestedTag : requestedTags) {
if (template.hasTag(requestedTag)) {
templates.add(template);
break;
}
}
}
Set<Tag> tags = new HashSet<>();
for (Template template : templates) {
tags.addAll(template.getTags());
}
templateTable.setTemplates(templates);
tagList.setInput(tags);
tagList.getList().select(0);
form.setWeights(new int[] { 20, 80 });
}
@Override
public IWizardPage getNextPage() {
Template template = templateTable.getSelectedTemplate();
if (template != null) {
try {
IWorkbenchWizard nextWizard = template.getWizard();
nextWizard.addPages();
return nextWizard.getPages()[0];
} catch (CoreException e) {
Activator.log(e);
}
}
return super.getNextPage();
}
}

View file

@ -0,0 +1,48 @@
package org.eclipse.tools.templates.ui.internal;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends AbstractUIPlugin {
private static Activator plugin;
private TemplateExtension templateExtension;
@Override
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
templateExtension = new TemplateExtension();
}
@Override
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
public static String getId() {
return plugin.getBundle().getSymbolicName();
}
public static TemplateExtension getTemplateExtension() {
return plugin.templateExtension;
}
public static void log(Exception e) {
if (e instanceof CoreException) {
plugin.getLog().log(((CoreException) e).getStatus());
} else {
plugin.getLog().log(new Status(IStatus.ERROR, getId(), e.getLocalizedMessage(), e));
}
}
}

View file

@ -0,0 +1,44 @@
package org.eclipse.tools.templates.ui.internal;
import org.eclipse.core.runtime.IConfigurationElement;
public class Tag {
public static final String ALL_ID = "all"; //$NON-NLS-1$
public String id;
public String label;
public Tag(IConfigurationElement element) {
id = element.getAttribute("id"); //$NON-NLS-1$
label = element.getAttribute("label"); //$NON-NLS-1$
}
public Tag(String id, String label) {
this.id = id;
this.label = label;
}
public String getId() {
return id;
}
public String getLabel() {
return label;
}
@Override
public int hashCode() {
return id.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Tag) {
return id.equals(((Tag) obj).id);
} else {
return false;
}
}
}

View file

@ -0,0 +1,65 @@
package org.eclipse.tools.templates.ui.internal;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Composite;
public class TagListViewer extends ListViewer {
public TagListViewer(Composite parent, int style) {
super(parent, style);
setLabelProvider(new LabelProvider() {
@Override
public String getText(Object element) {
if (element instanceof Tag) {
return ((Tag) element).getLabel();
} else {
return super.getText(element);
}
}
});
setContentProvider(new IStructuredContentProvider() {
private Tag[] tags;
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
if (newInput != null) {
@SuppressWarnings("unchecked")
Collection<Tag> tagsList = (Collection<Tag>) newInput;
tags = tagsList.toArray(new Tag[tagsList.size()]);
Arrays.sort(tags, new Comparator<Tag>() {
@Override
public int compare(Tag o1, Tag o2) {
// Keep all at the top
if (o1.getId().equals(Tag.ALL_ID)) {
return -1;
}
if (o2.getId().equals(Tag.ALL_ID)) {
return 1;
}
return o1.getLabel().compareTo(o2.getLabel());
}
});
}
}
@Override
public void dispose() {
}
@Override
public Object[] getElements(Object inputElement) {
return tags;
}
});
}
}

View file

@ -0,0 +1,73 @@
package org.eclipse.tools.templates.ui.internal;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.IWorkbenchWizard;
import org.eclipse.ui.plugin.AbstractUIPlugin;
public class Template {
private final TemplateExtension parent;
private final IConfigurationElement element;
private Map<String, Tag> tags;
public Template(TemplateExtension parent, IConfigurationElement element) {
this.parent = parent;
this.element = element;
}
public String getId() {
return element.getAttribute("id"); //$NON-NLS-1$
}
public String getLabel() {
return element.getAttribute("label"); //$NON-NLS-1$
}
public String getDescription() {
IConfigurationElement[] descs = element.getChildren("description"); //$NON-NLS-1$
return descs.length > 0 ? descs[0].getValue() : null;
}
public ImageDescriptor getIcon() {
String iconPath = element.getAttribute("icon"); //$NON-NLS-1$
return AbstractUIPlugin.imageDescriptorFromPlugin(element.getNamespaceIdentifier(), iconPath);
}
private void initTags() {
if (tags == null) {
tags = new HashMap<>();
for (IConfigurationElement ref : element.getChildren("tagReference")) { //$NON-NLS-1$
String id = ref.getAttribute("id"); //$NON-NLS-1$
Tag tag = parent.getTag(id);
if (tag != null) {
tags.put(tag.getId(), tag);
}
}
}
}
public void addTag(Tag tag) {
initTags();
tags.put(tag.getId(), tag);
}
public boolean hasTag(String tagId) {
initTags();
return tags.containsKey(tagId);
}
public Collection<Tag> getTags() {
return tags.values();
}
public IWorkbenchWizard getWizard() throws CoreException {
return (IWorkbenchWizard) element.createExecutableExtension("wizard"); //$NON-NLS-1$
}
}

View file

@ -0,0 +1,75 @@
package org.eclipse.tools.templates.ui.internal;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
public class TemplateExtension {
private Map<String, Template> templates;
private Map<String, Tag> tags;
private void init() {
if (templates != null)
return;
templates = new HashMap<>();
tags = new HashMap<>();
IExtensionRegistry registry = Platform.getExtensionRegistry();
IExtensionPoint point = registry.getExtensionPoint(Activator.getId(), "templates"); //$NON-NLS-1$
// tags
Tag allTag = new Tag(Tag.ALL_ID, "All");
tags.put(allTag.getId(), allTag);
for (IConfigurationElement element : point.getConfigurationElements()) {
if (element.getName().equals("tag")) { //$NON-NLS-1$
Tag tag = new Tag(element);
tags.put(tag.getId(), tag);
}
}
// templates
for (IConfigurationElement element : point.getConfigurationElements()) {
if (element.getName().equals("template")) { //$NON-NLS-1$
Template template = new Template(this, element);
templates.put(template.getId(), template);
template.addTag(allTag);
}
}
// template extensions
for (IConfigurationElement element : point.getConfigurationElements()) {
if (element.getName().equals("templateExtension")) { //$NON-NLS-1$
String templateId = element.getAttribute("templateId"); //$NON-NLS-1$
Template template = templates.get(templateId);
if (template != null) {
for (IConfigurationElement tagRef : element.getChildren("tagReference")) { //$NON-NLS-1$
String tagId = tagRef.getAttribute("id"); //$NON-NLS-1$
Tag tag = tags.get(tagId);
if (tag != null) {
template.addTag(tag);
}
}
}
}
}
}
public Collection<Template> getTemplates() {
init();
return templates.values();
}
public Tag getTag(String id) {
init();
return tags.get(id);
}
}

View file

@ -0,0 +1,148 @@
package org.eclipse.tools.templates.ui.internal;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Widget;
public class TemplateTable implements Listener {
private final Table table;
private Font fontBold;
private Font fontDefault;
private Map<ImageDescriptor, Image> images = new HashMap<>();
private static final Rectangle EMPTY_IMAGE_BOUNDS = new Rectangle(0, 0, 48, 48);
public TemplateTable(Composite parent, int style) {
table = new Table(parent, style);
table.addListener(SWT.MeasureItem, this);
table.addListener(SWT.EraseItem, this);
table.addListener(SWT.PaintItem, this);
table.addListener(SWT.Dispose, this);
}
public Table getTable() {
return table;
}
public void setTemplates(Collection<Template> templates) {
table.clearAll();
for (Template template : templates) {
TableItem item = new TableItem(table, SWT.NONE);
item.setData(template);
}
}
public Template getSelectedTemplate() {
TableItem[] items = table.getSelection();
if (items.length > 0) {
return (Template) items[0].getData();
} else {
return null;
}
}
@Override
public void handleEvent(Event event) {
switch (event.type) {
case SWT.MeasureItem:
computeItemArea(event);
break;
case SWT.PaintItem:
paintItem(event);
break;
case SWT.EraseItem:
computeItemArea(event);
break;
case SWT.Dispose:
for (Image image : images.values()) {
image.dispose();
}
break;
}
}
private void computeItemArea(Event event) {
event.width = table.getClientArea().width - event.x;
event.height = 56; // 48 for icon, 8 buffer
}
private void paintItem(Event event) {
Widget w = event.item;
GC gc = event.gc;
if (fontDefault == null) {
Font font = gc.getFont();
FontData[] data = font.getFontData();
if (data.length > 0) {
FontData d = data[0];
FontData normal = new FontData(d.getName(), d.getHeight(), // Math.round(d.getHeight()
// *
// .85F),
d.getStyle() | SWT.ITALIC);
fontDefault = new Font(event.display, normal);
FontData bold = new FontData(d.getName(), Math.round(d.getHeight() * 1.15F), d.getStyle() | SWT.BOLD);
fontBold = new Font(event.display, bold);
}
}
if (w instanceof TableItem) {
TableItem item = (TableItem) w;
Template template = (Template) item.getData();
ImageDescriptor imageDesc = template.getIcon();
Image image = images.get(imageDesc);
if (image == null) {
image = imageDesc.createImage();
images.put(imageDesc, image);
}
Rectangle rect = EMPTY_IMAGE_BOUNDS;
int y = 0;
if (image != null) {
rect = image.getBounds();
y = event.y + Math.max(0, (event.height - rect.height) / 2);
gc.drawImage(image, event.x + 4, y);
}
gc.setFont(fontBold);
String name = template.getLabel();
Point nameExtent = gc.textExtent(name, SWT.DRAW_TRANSPARENT);
int iconMargin = 10;
gc.drawText(name, rect.x + rect.width + iconMargin, y, SWT.DRAW_TRANSPARENT);
gc.setFont(fontDefault);
int flags = SWT.DRAW_TRANSPARENT | SWT.DRAW_DELIMITER;
String description = template.getDescription();
int width = table.getClientArea().width;
if (description != null) {
Point descExt = gc.textExtent(description, flags);
int descWidth = width - (rect.x + rect.width + iconMargin);
if (descExt.x > descWidth) {
FontMetrics fm = gc.getFontMetrics();
int averageCharWidth = fm.getAverageCharWidth();
int charsMaxNumberInRow = descWidth / averageCharWidth;
if (description.length() > charsMaxNumberInRow) {
String firstLine = description.substring(0, charsMaxNumberInRow);
int lastWS = firstLine.lastIndexOf(' ');
int endIndex = lastWS + 1 + charsMaxNumberInRow;
description = firstLine.substring(0, lastWS) + '\n'
+ description.substring(lastWS + 1, Math.min(endIndex, description.length()));
}
}
gc.drawText(description, rect.x + rect.width + iconMargin, y + nameExtent.y + 2, flags);
}
}
}
}